

#ifndef PHYSICSWORLD_H
#define PHYSICSWORLD_H

#include <cmexport.h>
#include <iobject.h>
#include <math/vector.h>
#include <physics/motionstate.h>
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>

#define BTVECTOR3(v) btVector3 ((v).x, (v).y, (v).z)
#define BTVECTOR3PTR(v) btVector3 ((v)->x, (v)->y, (v)->z)
#define CEBTVECTOR3(v) ceVector3f ((v).x(), (v).y(), (v).z())
#define CEBTVECTOR3PTR(v) ceVector3f ((v)->x(), (v)->y(), (v)->z())

/**
 * \addtogroup physics
 * @{
 */

/**
 * @brief One physics simulated world.
 */
class CM_API cmPhysicsWorld : public iObject
{
  CE_OBJECT
private:
  btCollisionConfiguration  *_config;
  btDispatcher              *_dispatcher;
  btBroadphaseInterface     *_broadphase;
  btConstraintSolver        *_solver;
  btDiscreteDynamicsWorld   *_world;


public:
  cmPhysicsWorld();
  virtual ~cmPhysicsWorld ();

  void Setup ();

  void SetGravity (const ceVector3f& gravity);
  void Step (float timeStep = 1.0f / 60.0f);

  btDiscreteDynamicsWorld* GetWorld ();
  const btDiscreteDynamicsWorld* GetWorld () const;

  ceEntityNode* GetEntityNode (btCollisionObject* obj);

  btRigidBody* AddStaticRigidBody (const ceMatrix4f& matrix, btCollisionShape* shape);
  btRigidBody* AddStaticRigidBody (ceEntityNode* node, btCollisionShape* shape);
  btRigidBody* AddKinematicRigidBody (ceEntityNode* node, btCollisionShape* shape);
  btRigidBody* AddDynamicRigidBody (ceEntityNode* node, btCollisionShape* shape, float mass = 1.0f);
  btRigidBody* AddDynamicRigidBody (ceEntityNode* node, btCollisionShape* shape, ceVector3f inertia, float mass = 1.0f);

  void RemoveRigidBody (btRigidBody* body);

};

/** @} */

#endif // PHYSICSWORLD_H
